/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.zumbits.avd.storage;

import br.com.zumbits.avd.Constants;
import br.com.zumbits.avd.server.Base64;
import br.com.zumbits.avd.sqlite.FilesSQLite;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author zumbits
 */
public class StorageManagerSqlite {

    public static final String DAV = ".dav";
    public static final String storegePath = "/home/pet/madnexus/avd/storege";
    //
    private FilesSQLite filesSQLite;

    public StorageManagerSqlite() {
    }

    private void Log(String str) {
        FileWriter writer = null;
        try {
            File file = new File(storegePath + File.separator + "log.txt");

            writer = new FileWriter(file);

            writer.write(str);
        } catch (IOException ex) {
            Logger.getLogger(StorageManager.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                writer.close();
            } catch (IOException ex) {
                Logger.getLogger(StorageManager.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private String getRealPath(String path) {
        return storegePath + File.separator + path;
    }

    public long getFreeSpace(String path) {
        return new File(getRealPath(path)).getFreeSpace();
    }

    public long getTotalSpace(String path) {
        return new File(getRealPath(path)).getTotalSpace();
    }

    public long getUsableSpace(String path) {
        return new File(getRealPath(path)).getUsableSpace();
    }

    public int getVersion(String path) {
        int version = -1;

        try {
            filesSQLite = new FilesSQLite(getRealPath(path));
            filesSQLite.select(getRealPath(path));
            filesSQLite.next();

            version = filesSQLite.getInt(getRealPath(path));

            filesSQLite.getResultSet().close();
            filesSQLite.disconnect();
            filesSQLite = null;
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(StorageManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(StorageManager.class.getName()).log(Level.SEVERE, null, ex);
        }

        return version;
    }

    public void setVersion(String path, int version) {
        try {
            filesSQLite = new FilesSQLite(getRealPath(path));
            filesSQLite.insert(getRealPath(path), version);
            filesSQLite.disconnect();
            filesSQLite = null;
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(StorageManager.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(StorageManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public boolean exists(String path) {
        return new File(getRealPath(path)).exists();
    }

    public String listFiles(String path) {
        String list = "";

        File currDir = new File(getRealPath(path));
        File listFiles[] = currDir.listFiles();

        for (int i = 0; i < listFiles.length; i++) {
            if (listFiles[i].isDirectory()) {
                list +=
                        Constants.TAB + "<folder>" + Constants.NEWLINE +
                        Constants.TAB + Constants.TAB + "<name>" + listFiles[i].getName() + "</name>" + Constants.NEWLINE +
                        Constants.TAB + "</folder>" + Constants.NEWLINE;
            }
        }

        for (int i = 0; i < listFiles.length; i++) {
            if (listFiles[i].isFile()) {
                list +=
                        Constants.TAB + "<file>" + Constants.NEWLINE +
                        Constants.TAB + Constants.TAB + "<name>" + listFiles[i].getName() + "</name>" + Constants.NEWLINE +
                        Constants.TAB + Constants.TAB + "<size>" + listFiles[i].length() + "</size>" + Constants.NEWLINE +
                        Constants.TAB + Constants.TAB + "<version>" + getVersion(path) + "</version>" + Constants.NEWLINE +
                        Constants.TAB + "</file>" + Constants.NEWLINE;
            }
        }

        return list;
    }

    public boolean createFolder(String path) {
        boolean ok = new File(getRealPath(path)).mkdir();

        if (ok) {
            try {
                filesSQLite = new FilesSQLite(getRealPath(path));

                filesSQLite.createTable();
                filesSQLite = null;
            } catch (ClassNotFoundException ex) {
                Log(ex.getMessage() + " fuuuu1");
                //return false;
            } catch (SQLException ex) {
                Log(ex.getMessage() + " fuuuu2");
                //return false;
            }
        }

        return ok;
    }

    public boolean delete(String path) {
        try {
            String name = path.substring(path.lastIndexOf(File.separator));
            filesSQLite = new FilesSQLite(getRealPath(path));

            filesSQLite.delete(name);
            filesSQLite.disconnect();
            filesSQLite = null;
        } catch (ClassNotFoundException ex) {
            Log(ex.getMessage());
        } catch (SQLException ex) {
            Log(ex.getMessage());
        }

        return new File(getRealPath(path)).delete();
    }

    public boolean move(String path, String newPath) {
        boolean moveDisk = new File(getRealPath(path)).renameTo(new File(getRealPath(newPath)));

        String name = path.substring(path.lastIndexOf(File.separator));
        String newName = newPath.substring(newPath.lastIndexOf(File.separator));

        if (moveDisk) {
            int version = getVersion(getRealPath(path));
            try {
                filesSQLite = new FilesSQLite(getRealPath(path));

                filesSQLite.delete(name);
                filesSQLite.disconnect();

                filesSQLite = new FilesSQLite(getRealPath(newPath));
                filesSQLite.insert(newName, version);
                filesSQLite.disconnect();

                filesSQLite = null;
            } catch (ClassNotFoundException ex) {
                Log(ex.getMessage());
            } catch (SQLException ex) {
                Log(ex.getMessage());
            }
        }

        return moveDisk;
    }

    public boolean copy(String path, String copyPath) throws IOException {
        File inputFile = new File(path);
        File outputFile = new File(copyPath);

        if (copyPath.equals(path)) {
            return false;
        }

        if (inputFile.isDirectory()) {
            //Para linux somente
            Runtime.getRuntime().exec("cp -R " + path + " " + copyPath);
        } else if (inputFile.isFile()) {
            try {
                String name = copyPath.substring(copyPath.lastIndexOf(File.separator));
                int version = getVersion(getRealPath(path));

                filesSQLite = new FilesSQLite(getRealPath(copyPath));
                filesSQLite.insert(name, version);
                filesSQLite.disconnect();
                filesSQLite = null;

                FileReader in = new FileReader(inputFile);
                FileWriter out = new FileWriter(outputFile);
                int c;

                while ((c = in.read()) != -1) {
                    out.write(c);
                }

                in.close();
                out.close();

                return true;
            } catch (ClassNotFoundException ex) {
                Log(ex.getMessage());
            } catch (SQLException ex) {
                Log(ex.getMessage());
            }
        }

        return false;
    }

    public String fileURL_SAFE_B64(String path) {
        FileInputStream fileInputStream = null;

        try {
            File file = new File(getRealPath(path));
            fileInputStream = new FileInputStream(file);

            byte[] b = new byte[(int) file.length()];
            fileInputStream.read(b);

            return Base64.encodeBytes(b, Base64.URL_SAFE);
        } catch (FileNotFoundException ex) {
            Log(ex.getMessage());
        } catch (IOException ex) {
            Log(ex.getMessage());
        } finally {
            try {
                fileInputStream.close();
            } catch (IOException ex) {
                Log(ex.getMessage());
            }
        }

        return null;
    }

    public int upload(String path, String data, int version) {
        try {
            String realPath = getRealPath(path);
            String name = realPath.substring(realPath.lastIndexOf(File.separator));

            try {
                filesSQLite = new FilesSQLite(realPath);
                filesSQLite.insert(name, version);
                filesSQLite.disconnect();
                filesSQLite = null;
            } catch (ClassNotFoundException ex) {
                Log(ex.getMessage());
            } catch (SQLException ex) {
                Log(ex.getMessage());
            }

            byte[] bytes = Base64.decode(data, Base64.URL_SAFE);
            File file = new File(realPath);

            FileOutputStream fileOutputStream = new FileOutputStream(file);

            fileOutputStream.write(bytes);
            fileOutputStream.close();

            return 0;
        } catch (IOException ex) {
            Log(ex.getMessage());
        }

        return 3;
    }
}
